﻿#include "utils_string.hpp"
#include <random>
#include <iomanip>
#include <sstream>

#ifdef WIN32

#include <Windows.h>

#endif

namespace bz {

#ifdef WIN32
	std::wstring utils_string::ascii_unicode(const std::string & str)
	{
		int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);

		wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);

		MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen);

		std::wstring ret_str = pUnicode;

		free(pUnicode);

		return ret_str;
	}

	std::string utils_string::unicode_ascii(const std::wstring & wstr)
	{
		int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
		char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
		WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
		std::string ret_str = pAssii;
		free(pAssii);
		return ret_str;
	}

	std::string utils_string::ascii_utf8(const std::string & str)
	{
		return unicode_utf8(ascii_unicode(str));
	}

	std::string utils_string::utf8_ascii(const std::string & utf8)
	{
		return unicode_ascii(utf8_unicode(utf8));
	}

	std::string utils_string::unicode_utf8(const std::wstring & wstr)
	{
		int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
		char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
		WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
		std::string ret_str = pAssii;
		free(pAssii);
		return ret_str;
	}

	std::wstring utils_string::utf8_unicode(const std::string & utf8)
	{
		int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, nullptr, 0);
		wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
		MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, pUnicode, unicodeLen);
		std::wstring ret_str = pUnicode;
		free(pUnicode);
		return ret_str;
	}
#endif
	void utils_string::split(const std::string& s, std::vector<std::string>& tokens, const std::string & delimiters)
	{
		std::string::size_type lastPos = s.find_first_not_of(delimiters, 0);
		std::string::size_type pos = s.find_first_of(delimiters, lastPos);
		while (std::string::npos != pos || std::string::npos != lastPos) {
			tokens.push_back(s.substr(lastPos, pos - lastPos));
			lastPos = s.find_first_not_of(delimiters, pos);
			pos = s.find_first_of(delimiters, lastPos);
		}
	}


	std::vector<std::string> utils_string::split(const std::string& str, const std::string& delimiter)
	{
		std::vector<std::string> result;
		size_t start = 0;
		size_t end = str.find(delimiter);

		while (end != std::string::npos) {
			result.push_back(str.substr(start, end - start));
			start = end + delimiter.length();
			end = str.find(delimiter, start);
		}

		// 添加最后一个子串
		result.push_back(str.substr(start));

		return result;
	}

	


	bool utils_string::contains(const std::string& str, const std::string& target)
	{
		return str.find(target) != std::string::npos;
	}


	void utils_string::replace_all(std::string& str, const std::string& oldstr, const std::string& newstr)
	{

		while (true)
		{
			std::string::size_type pos(0);
			if ((pos = str.find(oldstr)) != std::string::npos) {
				str.replace(pos, oldstr.length(), newstr);
			}
			else
			{
				break;
			}

		}

	}

	// 去除字符串开头的空白字符
	std::string utils_string::ltrim(const std::string& s) {
		size_t start = s.find_first_not_of(" \t\n\r"); // 查找第一个非空白字符的位置
		return (start == std::string::npos) ? "" : s.substr(start);
	}

	// 去除字符串末尾的空白字符
	std::string utils_string::rtrim(const std::string& s) {
		size_t end = s.find_last_not_of(" \t\n\r"); // 查找最后一个非空白字符的位置
		return (end == std::string::npos) ? "" : s.substr(0, end + 1);
	}

	// 去除字符串两端的空白字符
	std::string utils_string::trim(const std::string& s) {
		return rtrim(ltrim(s));
	}


	std::string utils_string::fromLocal8(const char* str)
	{
#ifdef WIN32
		return utils_string::ascii_utf8(str);
#else
		return std::string(str);
#endif
		
	}

	// 生成随机的16进制数字
	std::string generate_hex(unsigned int len) {
		std::random_device rd;
		std::mt19937 gen(rd());
		std::uniform_int_distribution<> dis(0, 15);

		std::stringstream ss;
		for (int i = 0; i < len; ++i) {
			ss << std::hex << dis(gen);
		}

		return ss.str();
	}

	// 生成UUID
	std::string utils_string::generate_uuid()
	{
		return generate_hex(8) + "-" +
			generate_hex(4) + "-" +
			generate_hex(4) + "-" +
			generate_hex(4) + "-" +
			generate_hex(12);
	}
}